//-------------------------------------------------------------------
//	Copyright (c) 2010-2012  Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_WINAPI_SHARED_WINDOW_H
#define _UX_WINAPI_SHARED_WINDOW_H

#include "WinAPI.h"
#include "../IWindow.h"
#include "../../Core/CCore.h"

#ifdef PLATFORM_WINDOWS

namespace Engine
{
namespace CoreSystems
{

	//
	// Window
	//

	class _EXPORT_ CSharedWindow : public IWindow
	{
	private:
		struct TListener
		{
			IWindowEventListener *	pListener;
			e_win_event::type		eEvents;
			///
			TListener(IWindowEventListener *listener, e_win_event::type events): pListener(listener), eEvents(events) {}
		};

		enum EPause : uint8
		{
			NO_FOCUS	= 0x1,
			USER_PAUSE	= 0x2,
			QUIT_ENGINE	= 0x4,
		};

		typedef array< TListener >			event_listeners_t;
		typedef array< IWindowUpdater *>	wnd_updaters_t;

	private:
		CCore		*		_pCore;
		CInput				_cInput;
		TThread				_sThread;
		operations_queue_t	_aOpQueue;
		TCriticalSection	_sCSLockQueue;

		string				_sAppCaption;
		event_listeners_t	_aEvLists;
		wnd_updaters_t		_aUpdaters;
		HKL					_pKeyboardInput;
		uint				_uFPSTimer,
							_uFPSCount;
		uint8				_uPause;
		volatile bool		_bIsLooping;
		bool				_bAllowPause,
							_bFPSInCaption;

	private:
		LRESULT _MsgProc(const TSystemMsg &sMsg);
		void    _SendEvent(const TWindowEvent &sEvent) const;
		void    _Update();
		void	_ProcessQueue();
		int		_MainLoop();
		bool	_ChangeWindowParams(const TRenderParams &sRParams, bool bShow);
		bool	_Start(e_thread_priority::type ePriority, CCore *pCore);
		bool	_AddSharedWindow(IWindow *pWindow);

		static DWindowProc( _s_WinProc );
		static DThreadProc( _s_ThreadProc );

	public:
		CSharedWindow();
		~CSharedWindow();
		
		// IWindow //
		bool  Init();
		bool  MainLoop();
		void  MakeCurrent() const		{ OSAPI()->MakeCurrent( _sHandles ); }
		bool  Show()					{ return OSAPI()->ShowWindow( _sHandles ); }
		bool  Hide()					{ return OSAPI()->HideWindow( _sHandles ); }
		bool  IsPaused()				{ return _uPause != 0 && _bAllowPause; }
		void  AllowPause(bool bAllow);
		bool  Quit();

		CInput * GetInputSystems()		{ return &_cInput; }

		void  AddEventListener(IWindowEventListener *pEvList, e_win_event::type eEvents);
		void  RemoveEventListener(IWindowEventListener *pEvList);

		void  AddUpdater(IWindowUpdater *pUpd);
		void  RemoveUpdater(IWindowUpdater *pUpd);
		
		void  ShowFPS(bool bShow);
		bool  SetCaption(const char *pCaption);
		
		bool  ChangeWindowParams(const TRenderParams &sRParams);
		
		bool  GetSharedWindow(e_thread::type eType, IWindow *&pWindow);
		bool  FreeSharedWindow(IWindow *pWindow);
		
		void  SendEvent(const TWindowEvent &sEvent);

		// IThread //
		bool  Push(IOperation *pOp, bool bHighPriority = false);
		void  Exit();
		bool  Pause();
		bool  Resume();
		bool  IsCurrent();


		// CEngBaseObject //
		void  Release();
	};

//-------------------------------------------------------------------

}	// CoreSystems
}	// Engine

#endif	// PLATFORM_WINDOWS

#endif	// _UX_WINAPI_SHARED_WINDOW_H